package com.iflytek.sbd.utils;

import cn.afterturn.easypoi.entity.vo.NormalExcelConstants;
import com.google.common.collect.Lists;
import com.iflytek.sbd.exception.CustomClException;
import com.iflytek.sbd.file.ExportView;
import com.lowagie.text.pdf.BaseFont;
import freemarker.template.Configuration;
import freemarker.template.Template;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.Workbook;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.web.multipart.MultipartFile;
import org.xhtmlrenderer.pdf.ITextRenderer;

import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletResponse;
import java.io.*;
import java.nio.charset.StandardCharsets;
import java.util.*;

/**
 * @program: myes
 * @description: 导出导出文件工具类
 * @author: 陈英俊
 * @create: 2021-09-24 14:01
 */
@Slf4j
public class FileUtils {


    // 工具类私有构造方法
    private FileUtils() {
    }

    /**
     * 得到文件后缀名
     *
     * @param file 前端上传文件对象
     * @return
     */
    public static String getFileSuffixName(MultipartFile file) {

        if (file == null) throw new CustomClException("500", "文件不可以为空");
        // 得到原始文件名
        String originalFilename = file.getOriginalFilename();
        if (StringUtils.isEmpty(originalFilename)) throw new CustomClException("500", "文件名是空");
        return originalFilename.substring(originalFilename.lastIndexOf(".") + 1).toLowerCase().trim();
    }

    /**
     * @param fileSuffixName       当前上传的文件后缀名
     * @param commonFileSuffixName 通用的文件允许上传类型,一般配置在配置文件 格式: txt,mp3,mp4
     * @return
     */
    public static void checkFileSuffixName(String fileSuffixName, String commonFileSuffixName) {
        log.info("通用的文件允许上传类型是:{}", commonFileSuffixName);
        List<String> list = Arrays.asList(commonFileSuffixName.toLowerCase().split("(,)"));
        if (!list.contains(fileSuffixName)) throw new CustomClException("500", "上传文件格式是非法格式!");
    }


    /**
     * 得到工作簿对象
     *
     * @param file
     * @return
     * @throws IOException
     */
    public static Workbook getWorkBook(MultipartFile file) throws IOException {
        //这样写  excel 能兼容03和07
        InputStream is = file.getInputStream();
        Workbook hssfWorkbook = null;
        try {
            hssfWorkbook = new HSSFWorkbook(is);
        } catch (Exception ex) {
            is = file.getInputStream();
            hssfWorkbook = new XSSFWorkbook(is);
        }
        return hssfWorkbook;
    }

    public static List<Map<String, Object>> getNeedListMap(List<ExportView> moreViewList) {
        List<Map<String, Object>> exportParamList = Lists.newArrayList();
        //迭代导出对象，将对应的配置信息写入到实际的配置中
        for (ExportView view : moreViewList) {
            Map<String, Object> valueMap = new HashMap<>();
            valueMap.put("title", view.getExportParams());
            valueMap.put(NormalExcelConstants.DATA_LIST, view.getDataList());
            valueMap.put(NormalExcelConstants.CLASS, view.getCls());
            exportParamList.add(valueMap);
        }
        return exportParamList;
    }

    /**
     * 导出excel对象
     *
     * @param response httpResponse对象
     * @param workbook workBook对象
     * @param fileName 导出文件名
     * @throws Exception 异常抛出
     */
    public static void exportByOriginName(HttpServletResponse response, Workbook workbook, String fileName) throws Exception {
        response.reset();
        response.setContentType("application/vnd.ms-excel");

        response.setHeader("Content-disposition", "attachment; filename=" + new String(fileName.getBytes("gb2312"), StandardCharsets.ISO_8859_1) + ".xls");
        ServletOutputStream outStream = null;
        try {
            outStream = response.getOutputStream();
            workbook.write(outStream);
        } finally {
            workbook.close();
            outStream.close();
        }
    }

    /**
     * 通过模板导出pdf文件
     *
     * @param data             数据
     * @param templateFileName 模板文件名
     * @throws Exception
     */
    public static ByteArrayOutputStream createPDF(Map<String, Object> data, String templateFileName) throws Exception {
        // 创建一个FreeMarker实例, 负责管理FreeMarker模板的Configuration实例
        Configuration cfg = new Configuration(Configuration.DEFAULT_INCOMPATIBLE_IMPROVEMENTS);
        // 指定FreeMarker模板文件的位置
        cfg.setClassForTemplateLoading(FileUtils.class, "/templates");
        ITextRenderer renderer = new ITextRenderer();
        OutputStream out = new ByteArrayOutputStream();
        try {
            // 设置 css中 的字体样式（暂时仅支持宋体和黑体） 必须，不然中文不显示
//            File directory = new File("src/main/resources");
//            String courseFile = directory.getCanonicalPath();
            renderer.getFontResolver().addFont("/templates/font/simsun.ttc", BaseFont.IDENTITY_H, BaseFont.NOT_EMBEDDED);
            // 设置模板的编码格式
            cfg.setEncoding(Locale.CHINA, "UTF-8");
            // 获取模板文件
            Template template = cfg.getTemplate(templateFileName, "UTF-8");
            StringWriter writer = new StringWriter();

            // 将数据输出到html中
            template.process(data, writer);
            writer.flush();

            String html = writer.toString();
            // 把html代码传入渲染器中
            renderer.setDocumentFromString(html);

            // 设置模板中的图片路径 （这里的images在resources目录下） 模板中img标签src路径需要相对路径加图片名 如<img src="images/xh.jpg"/>
//            String url = PDFTemplateUtil.class.getClassLoader().getResource("images").toURI().toString();
//            renderer.getSharedContext().setBaseURL(url);
            renderer.layout();

            renderer.createPDF(out, false);
            renderer.finishPDF();
            out.flush();
            return (ByteArrayOutputStream) out;
        } finally {
            if (out != null) {
                out.close();
            }
        }
    }
}
